﻿using System;
using System.ComponentModel;

namespace Eff.Extensions
{
    /// <summary>
    /// 类型转换扩展方法
    /// </summary>
    public static class ConvExt
    {
        public static bool AsBool(this object source, bool defvalue = false)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                bool.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        public static byte AsByte(this object source, byte defvalue = (byte)0)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                byte.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        public static DateTime AsDatetime(this object source, DateTime defvalue)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                DateTime.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        public static decimal AsDecimal(this object source)
        {
            return AsDecimal(source, 0);
        }

        public static decimal AsDecimal(this object source, decimal defvalue = 0)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                decimal.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        public static double AsDouble(this object source, double defvalue = 0)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                double.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        public static int AsInt(this object source, int defvalue = 0)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                int.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        public static long AsLong(this object source)
        {
            return AsLong(source, 0);
        }

        public static long AsLong(this object source, long defvalue = 0)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                long.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }



        public static short AsShort(this object source, short defvalue = (short)0)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                short.TryParse(source.ToString(), out defvalue);
            }
            return defvalue;
        }

        /// <summary>
        /// 在2.0的aspx页面下使用函数默认参数会报错，兼容2.0
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string AsString(this object source)
        {
            return AsString(source, "");
        }

        public static string AsString(this object source, string defvalue = "")
        {
            if ((source != null) && (source.ToString() != ""))
            {
                defvalue = source.ToString();
            }
            return defvalue;
        }


        /// <summary>
        /// 转换失败则返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static DateTime? AsDatetimeNull(this object source)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                DateTime value;
                if (DateTime.TryParse(source.ToString(), out value))
                    return value;
            }
            return null;
        }

        /// <summary>
        /// 转换为int，失败返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int? AsIntNull(this object source)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                int value;
                if (int.TryParse(source.ToString(), out value))
                    return value;

            }
            return null;
        }

        /// <summary>
        /// 转换为int，失败返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static long? AsLongNull(this object source)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                long value;
                if (long.TryParse(source.ToString(), out value))
                    return value;
            }
            return null;
        }
        /// <summary>
        /// 转换为bool，失败返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool? AsBoolNull(this object source)
        {
            if ((source != null) && (source.ToString() != ""))
            {
                bool value;
                if (bool.TryParse(source.ToString(), out value))
                    return value;
            }
            return null;
        }

        /// <summary>
        ///  类型转换
        ///  性能比AsInt()等稍差，在极度追求性能时请使用AsInt类方法
        /// </summary>
        /// <param name="value"></param>
        /// <param name="defaultValue"></param>
        /// <typeparam name="TValue"></typeparam>
        /// <returns></returns>
        public static TValue As<TValue>(this string value, TValue defaultValue)
        {
            try
            {
                TypeConverter converter = TypeDescriptor.GetConverter(typeof(TValue));
                if (converter.CanConvertFrom(typeof(string)))
                {
                    return (TValue)converter.ConvertFrom(value);
                }
                converter = TypeDescriptor.GetConverter(typeof(string));
                if (converter.CanConvertTo(typeof(TValue)))
                {
                    return (TValue)converter.ConvertTo(value, typeof(TValue));
                }
            }
            catch (Exception)
            {
            }
            return defaultValue;
        }

        /// <summary>
        /// 类型转换，转换失败返回默认值
        /// 性能比AsInt()等稍差，在极度追求性能时请使用AsInt类方法
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static TValue As<TValue>(this string value)
        {
            return value.As(default(TValue));
        }

        /// <summary>
        /// 判断类型
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool Is<TValue>(this string value)
        {
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(TValue));
            return (((converter != null) && converter.CanConvertFrom(typeof(string))) && converter.IsValid(value));
        }

        /// <summary>
        /// 是否Bool
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsBool(this string value)
        {
            return value.Is<bool>();
        }

        /// <summary>
        /// 是否DateTime
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsDateTime(this string value)
        {
            return value.Is<DateTime>();
        }

        /// <summary>
        /// 是否Decimal
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsDecimal(this string value)
        {
            return value.Is<decimal>();
        }

        /// <summary>
        /// 是否Float
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsFloat(this string value)
        {
            return value.Is<float>();
        }

        /// <summary>
        /// 是否Int
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsInt(this string value)
        {
            return value.Is<int>();
        }

    }
}
